package megrez.job.custom.component;

import java.lang.reflect.Method;

import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import megrez.job.common.ExceptionHelper;
import megrez.job.custom.domain.Config;
import megrez.job.custom.utils.SpringContextUtils;

/**
 * 计划任务
 * 
 * @author Lucky Yang
 * @since 2.6.9
 */
@Slf4j
@Getter
@RequiredArgsConstructor
public class ScheduledTask implements Runnable {
    private final Task task;
    private final TaskService taskSrc;

    private volatile boolean stop = false;


    @Override
    public void run() {
        if (stop) {
            log.warn("The task has been stopped: {}", task);
            return;
        }

        try {
            taskSrc.run(task);

            Config config = task.getConfig();
            final String className = config.getClassName();
            final String methodName = config.getMethodName();
            final String methodParams = config.getMethodParams();

            Object target = SpringContextUtils.getBean(Class.forName(className));
            Method method = null;
            boolean hasParams = StringUtils.hasText(methodParams);
            if (hasParams) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (hasParams) {
                method.invoke(target, methodParams);
            } else {
                method.invoke(target);
            }
            taskSrc.complete(task);
        } catch (Exception e) {
            taskSrc.error(task, ExceptionHelper.stacktraceToString(e));
        }

    }

    public boolean isStopped() {
        return this.stop;
    }

    public void stop() {
        stop = true;
        taskSrc.stop(task);
    }

    public void start() {
        taskSrc.start(task);
    }
}
